{-# OPTIONS -Wall #-}

--------------------------------------------------------------------------------
-- |
-- Module      :  Orca.Language.SignalIO
-- Copyright   :  (c) Stephen Tetley 2013
-- License     :  BSD3
--
-- Maintainer  :  stephen.tetley@gmail.com
-- Stability   :  unstable
-- Portability :  GHC
--
-- Signal input and output.
-- 
--------------------------------------------------------------------------------

module Orca.Language.SignalIO
  (

  -- * Signal input
    inm


  , ins
  , inq
  , soundin
  , diskin
  , diskin2

  -- * Signal output
  , out
  , outs1
  , outs2
  , outs
  , outq
  , soundout
  , soundouts

  -- * Sound file queries
  , filelen
  , filesr
  , filechnls
  , filepeak

  ) where

import Orca.Language.Prim
import Orca.Prim.InstMon


--------------------------------------------------------------------------------
-- Signal input

-- | Read mono audio. @in@ (Csound) has a name clash with Haskell 
-- so it is called @inm@ here.
--
-- > inm : () -> a1
--
-- WARNING: use only for orchestras with @nchnls=1@, see Csound 
-- reference. 
--
inm :: GenASig
inm = opcode1 "in" []




-- | Read stereo audio.
--
-- > ins : () -> (a1,a2)
-- 
ins :: GenSig2 ARate
ins = opcode2 "ins" []


-- | Read quad audio.
--
-- > inq : () -> (a1,a2,a3,a4)
--
inq :: GenSig4 ARate
inq = opcode4 "inq" []




soundin :: IString -> GenASig
soundin ifilcod = 
    opcode1 "soundin" [ getPExpr ifilcod ]



-- | stereo and quad versions need a naming scheme...
--
diskin :: IString -> KSig -> GenASig
diskin ifilcod kpitch = 
    opcode1 "diskin" [ getPExpr ifilcod, getPExpr kpitch ]


-- There is now a @diskin2@ opcode in Csound, this means we 
-- can\'t use numeral naming as an arity family for the stereo
-- and quad versions of @diskin@.

diskin2 :: IString -> KSig -> GenASig
diskin2 ifilcod kpitch = 
    opcode1 "diskin2" [ getPExpr ifilcod, getPExpr kpitch ]


--------------------------------------------------------------------------------
-- Signal output


-- | Write mono audio.
--
-- > out : asig -> ()
--
out :: ASig -> Code ()
out asig = 
    opcode0 "out" [ getPExpr asig ]

-- | Write channel 1 of stereo audio.
--
-- > outs1 : asig -> ()
-- 
outs1 :: ASig -> Code ()
outs1 asig = 
    opcode0 "outs1" [ getPExpr asig ]

-- | Write channel 2 of stereo audio.
--
-- > outs2 : asig -> ()
-- 
outs2 :: ASig -> Code ()
outs2 asig = 
    opcode0 "outs2" [ getPExpr asig ]

-- | Write stereo audio.
--
-- > out : asig1 * asig2 -> ()
--
outs :: ASig -> ASig -> Code ()
outs asig1 asig2 = 
    opcode0 "outs" [ getPExpr asig1, getPExpr asig2 ]




-- | Write quad audio.
--
-- > out : asig1 * asig2 * asig3 * asig4 -> ()
--
outq :: ASig -> ASig -> ASig -> ASig -> Code ()
outq asig1 asig2 asig3 asig4 = 
    opcode0 "outq" [ getPExpr asig1, getPExpr asig2
                   , getPExpr asig3, getPExpr asig4 ]

soundout :: ASig -> IString -> Code ()
soundout asig1 ifilcod = 
    opcode0 "soundout" [ getPExpr asig1, getPExpr ifilcod ]

soundouts :: ASig -> ASig -> IString -> Code ()
soundouts asigl asigr ifilcod = 
    opcode0 "soundout" [ getPExpr asigl, getPExpr asigr
                       , getPExpr ifilcod ]


--------------------------------------------------------------------------------
-- File queries


-- Strictly speaking, these should not return /signals/.

-- | Length in seconds...
--
filelen :: IString -> GenSig IFloat
filelen ifilcod = 
    opcode1 "filelen" [ getPExpr ifilcod ]

filesr :: IString -> GenSig IInt 
filesr ifilcod = 
   opcode1 "filesr" [ getPExpr ifilcod ]

filechnls :: IString -> GenSig IInt 
filechnls ifilcod = 
    opcode1 "filechnls" [ getPExpr ifilcod ]

filepeak :: IString -> GenSig IFloat
filepeak ifilcod = 
    opcode1 "filepeak" [ getPExpr ifilcod ]



--------------------------------------------------------------------------------
-- Printing and display

-- Note - can\'t type @print@ with current types as we have 3 
-- different iarg types: OString, OInt and OFloat.


